/*
* Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serialize, Serializer};

#[inline]
pub fn serialize_tuple<T, S, const N: usize>(arr: &[T; N], serializer: S) -> Result<S::Ok, S::Error> 
where T: Serialize, S: Serializer
{
    let mut seq = serializer.serialize_tuple(N)?;
    for e in arr {
        seq.serialize_element(e)?;
    }
    seq.end()
}

#[inline]
pub fn deserialize_tuple<'de, T, S, const N: usize>(deserializer: S) -> Result<[T; N], S::Error>
where T: Deserialize<'de>, S: Deserializer<'de>
{
    struct ArrayVisitor<T, const N: usize> {
        marker: std::marker::PhantomData<T>,
    }

    impl<'de, T, const N: usize> serde::de::Visitor<'de> for ArrayVisitor<T, N>
    where
        T: Deserialize<'de>,
    {
        type Value = [T; N];

        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
            write!(formatter, "an array of length {}", N)
        }

        fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
        where
            A: serde::de::SeqAccess<'de>,
        {
            use std::mem::MaybeUninit;
            let mut arr: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
            let mut i = 0;
            while i < N {
                match seq.next_element()? {
                    Some(val) => {
                        arr[i].write(val);
                        i += 1;
                    }
                    None => {
                        return Err(serde::de::Error::invalid_length(i, &self));
                    }
                }
            }

            // Transmute to [T; N]
            let out = unsafe { 
                let ptr = &mut arr as *mut _ as *mut [T; N];
                ptr.read()
            };
            Ok(out)
        }
    }

    deserializer.deserialize_tuple(N, ArrayVisitor::<T, N> { marker: std::marker::PhantomData })
}
